package com.dh.convert.rule;

import com.dh.convert.exception.ConvertInitException;
import com.dh.convert.rule.validator.AbstractValidator;
import com.dh.convert.rule.validator.Validator;
import com.dh.convert.rule.validator.ValidatorContext;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import org.reflections.Reflections;

import java.util.Set;

public class RuleLoader {

	private static final Reflections validatorScaner = new Reflections("com.dh.convert.rule.validator");

	private static final Reflections functionScaner = new Reflections("com.dh.convert.rule.function");

	public static void initRule() {
		try {
			Set<Class<? extends AbstractFunction>> functions = functionScaner.getSubTypesOf(AbstractFunction.class);
			for (Class<? extends AbstractFunction> functionClass : functions) {
				AviatorEvaluator.addFunction(functionClass.newInstance());
			}
			Set<Class<? extends AbstractValidator>> validators = validatorScaner.getSubTypesOf(AbstractValidator.class);
			for (Class<? extends AbstractValidator> validatorClass : validators) {
				addValidator(validatorClass);
			}
		} catch (Exception e) {
			throw new ConvertInitException("ruleLoader initRule error ", e);
		}
	}

	public static void addValidator(Class<? extends AbstractValidator> validator) throws InstantiationException, IllegalAccessException {
		Validator validatorAnnotation = validator.getDeclaredAnnotation(Validator.class);
		if (validatorAnnotation == null) {
			return;
		}
		if (ValidatorContext.contains(validatorAnnotation.value())) {
			throw new IllegalArgumentException(
					validatorAnnotation.value() + " is exist,please change the name");
		}

		AbstractValidator validatorObject = validator.newInstance();
		validatorObject.initialize();
		ValidatorContext.put(validatorAnnotation.value(), validatorObject);
	}

}
